/**

This file is part of MaCI/GIMnet.

MaCI/GIMnet is free software: you can redistribute it and/or modify it 
under the terms of the GNU Lesser General Public License as published 
by the Free Software Foundation, either version 3 of the License, or 
(at your option) any later version.

MaCI/GIMnet is distributed in the hope that it will be useful, but WITHOUT 
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public 
License for more details.

You should have received a copy of the GNU Lesser General Public 
License along with GIMnet. (See COPYING.LESSER) If not, see 
<http://www.gnu.org/licenses/>.

**/
// -*- coding:iso-8859-15 mode: c++ -*-
/** 
 * \file
 * \brief Player upper class header.
 * \author Matthieu Myrsky <matthieu.myrsky@tkk.fi>
 *
 * $Id: Player.hpp,v 1.7 2009-06-05 14:04:45 morsko Exp $
 *
 */
#ifndef _PLAYER_HPP_
#define _PLAYER_HPP_
#include <string>
#include <list>
#include <map>
#include "timestamp.hpp"
#include "PlayerModule.hpp"
#include "ownutils.h"
#include "owndebug.h"
#include "sync.hpp"
#include "thread.hpp"


class Player: private gim::CSync, 
              private gim::CThread
{
public:

  /**
   * Constructor
   * 
   */
  Player();
  
  
  /**
   * Destructor
   */
  ~Player();
  
  /**
   * Start playing the time list
   */
  void StartPlaying();

  /**
   * Pause playing the time list
   */
  void PausePlaying();

  /**
   * Stop playing the timelist and goes to beginning
   */
  void StopPlaying();
  
  /**
   * Sets wanted playing speed multiplier
   *
   * @param aPlayingSpeed speed multiplayer (must be >0)
   */
  void SetPlayingSpeed(float aPlayingSpeed);

  /**
   * Sets player to wanted time
   *
   * @param aCurrentNewTime time to jump
   */
  void SetCurrentTime(gim::time aCurrentNewTime);

  /**
   * Add a new playerModule to player.
   * @param aModule Pointer to module to add
   */
  void SetPlayerModule(PlayerModule *aModule);

  /**
   * Removes playerModule from player and removes all actions of module
   *
   * @param aModule Pointer to module to remove
   */
  void RemovePlayerModule(PlayerModule *aModule);

  /**
   * Gives begin and end time of player
   *
   * @param aBegin begin time of player(Time of first action of modules added to player)
   * @param aEnd   end time of player (time of last action of modules added to player)
   * @return       True if player has some action. false if not
   */
  bool GetTimeLimits(gim::time &aBegin,gim::time &aEnd);

  /**
   * Gives the current time of player and ratio 
   *
   * @param aCurrent      Time of current moment. 
   * @param aRatioFromAll ratio(0-1) of current moment. aRatioFromAll = timenow/wholeTime
   */
  void GetCurrentTime(gim::time &aCurrent, float &aRatioFromAll);

  /**
   * Set repeat mode on/off
   *
   * @param state  State of repeat mode
   */
  void SetRepeat(bool state);

  /**
   * Tells if player is playing or not
   *
   * @return true if playing, false if stopped or paused
   */
  bool IsPlaying(void);

  /**
   * Tells if the repeat mode is on or off
   *
   * @return True if repeat is on, else false
   */
  bool IsRepeat(void);

protected:
  bool iPlaying;          ///< state of player
  bool iRepeat;           ///< state of repeat mode
  float iPlayingSpeed;    ///< playing speed
  std::multimap<gim::time, PlayerModule*> iActionTimes;     ///< All actions are stored here
  std::multimap<gim::time, PlayerModule*>::iterator iCurrentTimeIterator; ///< Iterator of current time



  int ThreadFunction(const int aThreadNumber);
};

#endif
